package com.jar.netty_demo.Netty.task;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

public class ServerChatHandle extends SimpleChannelInboundHandler<String> {
    /**
     * 定义一个存放所有客户端的channel组
     */
    private static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     * 读取客户端的消息，并进行一个消息的转发，发送给除自己以外的其他人
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        Channel channel = ctx.channel();
        // 把耗费时间长的任务放到TaskQueue中，异步执行
        channel.eventLoop().execute(() -> {
            try {
                System.out.println("服务器阻塞中");
                Thread.sleep(10 * 1000);
                System.out.println("服务器阻塞结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        channels.writeAndFlush("【" + channel.remoteAddress() + "】：" + msg, channel1 -> !channel1.equals(channel));
    }

    /**
     * 在channel被启用的时候触发（在建立连接的时候）
     * 覆盖了 channelActive() 事件处理方法。服务端监听到客户端活动
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端【" + ctx.channel().remoteAddress() + "】上线了~");
    }

    /**
     * 在channel取消启动的时候触发（在关闭连接的时候）
     * 服务端监听到客户端活动
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端【" + ctx.channel().remoteAddress() + "】离线了~");
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        //channels.remove(channel);不用remove原因： channelgroup会自动删除当前channel
        channels.writeAndFlush("客户端【" + channel.remoteAddress() + "】离开聊天室");
        System.out.println("当前在线人数：" + channels.size());
    }

    /**
     * 每当从服务端收到【新】的客户端连接时
     * 1、给所有人发送消息
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        //将该客户端添加到客户端组中
        channels.add(channel);
        //给所有人发送客户端连接的消息；内部做了遍历
        channels.writeAndFlush("客户端【" + channel.remoteAddress() + "】进入聊天室");
        System.out.println("当前在线人数：" + channels.size());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //关闭通道
        ctx.close();
    }
}
